<template>
  <section class="page-container">
    <section class="options-bar-wrap">
      <el-tooltip
        content="打开"
        placement="top"
      >
        <section
          class="options__item"
          @click="openFile"
        >
          <el-icon
            v-if="loading"
            class="icon is-loading"
          >
            <loading />
          </el-icon>
          <base-svg-icon
            v-else
            icon-class="icon-add-image"
            class="icon"
          />
          <input
            ref="filElem"
            style="display: none;"
            type="file"
            accept="image/*"
            class="upload-file"
            @change="chooseImage"
          >
        </section>
      </el-tooltip>
      <div
        class="options__item"
        @click.prevent="handleSave"
      >
        保存
      </div>
      <div
        class="options__item"
        @click.prevent="handleReset"
      >
        重做
      </div>
      <el-tooltip
        content="缩小"
        placement="top"
      >
        <span
          class="options__item"
          @click="handleZoom(-0.2)"
        >
          <base-svg-icon
            icon-class="icon-minus"
            class="icon"
          />
        </span>
      </el-tooltip>
      <el-tooltip
        content="放大"
        placement="top"
      >
        <span
          class="options__item"
          @click="handleZoom(0.2)"
        >
          <base-svg-icon
            icon-class="icon-plus"
            class="icon"
          />
        </span>
      </el-tooltip>
      <el-tooltip
        content="正向旋转+90"
        placement="top"
      >
        <span
          class="options__item"
          @click="handleRotate(90)"
        >
          <base-svg-icon
            icon-class="icon-forward-rotation"
            class="icon"
          />
        </span>
      </el-tooltip>
      <el-tooltip
        content="反向旋转-90"
        placement="top"
      >
        <span
          class="options__item"
          @click="handleRotate(-90)"
        >
          <base-svg-icon
            icon-class="icon-reserve-rotation"
            class="icon"
          />
        </span>
      </el-tooltip>
      <el-tooltip
        content="上下翻转"
        placement="top"
      >
        <span
          class="options__item"
          @click="handleFlipX()"
        >
          <base-svg-icon
            icon-class="icon-reserve-x"
            class="icon"
          />
        </span>
      </el-tooltip>
      <el-tooltip
        content="左右翻转"
        placement="top"
      >
        <span
          class="options__item"
          @click="handleFlipY()"
        >
          <base-svg-icon
            icon-class="icon-reserve-y"
            class="icon"
          />
        </span>
      </el-tooltip>
    </section>
    <el-row
      class="cropper-content"
      :gutter="12"
    >
      <el-col
        :xs="24"
        :md="12"
      >
        <!-- 剪裁框 -->
        <section class="cropper">
          <img
            ref="originImage"
            :src="originImageSrc"
            alt=""
            width="100%"
          >
        </section>
      </el-col>
      <el-col
        :xs="24"
        :md="12"
      >
        <!-- 预览框 -->
        <div
          class="show-preview"
        >
          <div class="preview before" />
        </div>
      </el-col>
    </el-row>
  </section>
</template>

<script lang="ts">
import { ref, defineComponent, onMounted } from 'vue';

import { Loading } from '@element-plus/icons-vue';
import Cropper from 'cropperjs';
import 'cropperjs/dist/cropper.min.css';
import { ElMessage } from 'hive-plus';

import cropperDemoImgUrl from '@/assets/images/cropper-demo.jpeg';
import { downloadFileByBase64 } from '@/utils/file-tools';

export default defineComponent({
  name: 'ImageCroppingIndex',
  components: {
    Loading,
  },
  setup() {
    const filElem = ref();
    const originImageSrc = ref(cropperDemoImgUrl);
    const originImage = ref();
    const loading = ref(false);

    let theCropper:any;

    const handelInit = () => {
      theCropper = new Cropper(originImage.value, {
        viewMode: 1,
        dragMode: 'move',
        initialAspectRatio: 1,
        aspectRatio: 1,
        preview: '.preview',
        background: false,
        autoCropArea: 1,
        zoomOnWheel: true,
        restore: true,
        responsive: true,
      });
    };

    const openFile = () => {
      filElem.value.dispatchEvent(new MouseEvent('click'));
    };

    const chooseImage = () => {
      const inputFile = filElem.value.files[0];
      if (inputFile) {
        if (!/(gif|png|jpg|jpeg)$/i.test(inputFile.type)) {
          ElMessage({
            message: '上传头像图片只能是gif|png|jpg|jpeg 格式!',
            type: 'warning',
          });
          return false;
        }
        loading.value = true;
        const reader = new FileReader();
        reader.readAsDataURL(inputFile);
        reader.onload = (ev: ProgressEvent<FileReader>) => {
          originImageSrc.value = ev?.target?.result ?? '';
          theCropper.replace(originImageSrc.value);
        };
        setTimeout(() => {
          loading.value = false;
        }, 500);
        return true;
      }
      return false;
    };

    const handleSave = () => {
      const cropperImageUrl = theCropper.getCroppedCanvas({
        imageSmoothingQuality: 'high',
      }).toDataURL('image/jpeg');
      downloadFileByBase64(cropperImageUrl, `截取图片_${Date.now()}`);
    };

    const handleReset = () => {
      theCropper.reset();
    };

    const handleZoom = (ratio = 0.1) => {
      theCropper.zoom(ratio);
    };

    const handleRotate = (rotate = 90) => {
      theCropper.rotate(rotate);
    };

    const handleFlipX = () => {
      theCropper.scale(1, -1);
    };
    const handleFlipY = () => {
      theCropper.scale(-1, 1);
    };

    onMounted(() => {
      handelInit();
    });

    return {
      filElem,
      originImageSrc,
      originImage,
      loading,
      handelInit,
      openFile,
      chooseImage,
      handleSave,
      handleReset,
      handleZoom,
      handleRotate,
      handleFlipX,
      handleFlipY,
    };
  },
});
</script>

<style lang="scss" scoped>
.page-container {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  height: 100%;

  .options-bar-wrap {
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: center;
    height: 36px;
    padding: 0 4px;
    margin: 0 auto;
    margin-bottom: 12px;
    color: #fff;
    background-color: #2b2c2f;
    border-radius: 4px;

    .options__item {
      padding: 8px;
      margin: 0 4px;
      cursor: pointer;

      &:hover {
        background-color: #414244;
        border-radius: 4px;
      }
    }

    .icon {
      font-size: 18px;
    }
  }

  img {
    width: 100%;
    user-select: none;
  }

  .cropper-content {
    flex: 1;
    height: 100%;

    .cropper {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 100%;
      height: 100%;
      overflow: hidden;
    }

    .show-preview {
      display: flex;
      flex: 1;
      align-items: center;
      justify-content: center;
      width: 100%;
      height: 100%;
      overflow: hidden;
      background: #ccc;
    }

    .preview {
      width: 100%;
      height: 100%;
      overflow: hidden;
      background: #ccc;
      border: 1px solid #468ac8;
    }
  }
}
</style>
